package org.example.java8.collector;

import java.util.*;
import java.util.stream.Collectors;

public class CollectorsAction {
    private final static List<Dish> menu = Arrays.asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT),
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER),
            new Dish("rice", true, 350, Dish.Type.OTHER),
            new Dish("season fruit", true, 120, Dish.Type.OTHER),
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            new Dish("prawns", false, 300, Dish.Type.FISH),
            new Dish("salmon", false, 450, Dish.Type.FISH));

    public static void main(String[] args) {

        //testAveragingDouble();
        //testAveragingInt();
        //testAveragingLong();
        //testCollectingAndThen();
        //testCounting();
        //testGroupByFunction();
        //testGroupByFunctionAndCollector();
        //testGroupByFunctionAndSupplierAndCollector();
        testSummarizingInt();


    }

    private static void testAveragingDouble() {
        Optional.ofNullable(menu.stream().collect(Collectors.averagingDouble(Dish::getCalories)))
                .ifPresent(System.out::println);
    }

    private static void testAveragingInt() {
        Optional.ofNullable(menu.stream().collect(Collectors.averagingInt(Dish::getCalories)))
                .ifPresent(System.out::println);
    }

    private static void testAveragingLong() {
        Optional.ofNullable(menu.stream().collect(Collectors.averagingLong(Dish::getCalories)))
                .ifPresent(System.out::println);
    }

    private static void testCollectingAndThen() {
        Optional.of(menu.stream().collect(Collectors.collectingAndThen(
                Collectors.averagingInt(Dish::getCalories), a -> "The Average Calories is->" + a
        ))).ifPresent(System.out::println);

        //返回的list不能修改
        //List<Dish> list = menu.stream().filter(dish -> dish.getType().equals(Dish.Type.MEAT))
        //        .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
        //List<Dish> dishes = Collections.unmodifiableList(list);

        //返回的list可以修改
        List<Dish> list = menu.stream().filter(dish -> dish.getType().equals(Dish.Type.MEAT))
                .collect(Collectors.toList());
        list.add(new Dish("", false, 100, Dish.Type.OTHER));
        System.out.println(list);
    }

    private static void testCounting() {
        Optional.of(menu.stream().collect(Collectors.counting())).ifPresent(System.out::println);
    }

    private static void testGroupByFunction() {
        Optional.of(menu.stream().collect(Collectors.groupingBy(Dish::getType)))
                .ifPresent(System.out::println);
    }

    private static void testGroupByFunctionAndCollector() {
        Optional.of(menu.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.counting())))
                .ifPresent(System.out::println);

        Optional.of(menu.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.averagingInt(Dish::getCalories))))
                .ifPresent(System.out::println);
    }

    private static void testGroupByFunctionAndSupplierAndCollector() {
        //转换为TreeMap
        TreeMap<Dish.Type, Double> map = menu.stream().collect(Collectors.groupingBy(Dish::getType, TreeMap::new, Collectors.averagingInt(Dish::getCalories)));
        Optional.of(map.getClass()).ifPresent(System.out::println);
        Optional.of(map).ifPresent(System.out::println);
    }

    private static void testSummarizingInt() {
        IntSummaryStatistics result = menu.stream().collect(Collectors.summarizingInt(Dish::getCalories));
        Optional.of(result).ifPresent(System.out::println);
        result.getAverage();
    }

}
